package com.qymerge.manage.system.service.impl;

import com.qymerge.manage.core.bean.ActionResultRO;
import com.qymerge.manage.core.bean.DataTableRO;
import com.qymerge.manage.core.bean.PageRequest;
import com.qymerge.manage.core.bean.ReturnMap;
import com.qymerge.manage.core.constant.BaseConstants;
import com.qymerge.manage.core.enums.StatusTypes;
import com.qymerge.manage.core.utils.CommonUtil;
import com.qymerge.manage.core.utils.SHA256Enhanced;
import com.qymerge.manage.system.dao.*;
import com.qymerge.manage.system.dto.SysRoleDTO;
import com.qymerge.manage.system.dto.SysUserDTO;
import com.qymerge.manage.system.dto.SysUserSnapDTO;
import com.qymerge.manage.system.ro.*;
import com.qymerge.manage.system.service.ISystemService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *<p>Title: SystemService</p>
 *<p>Description: </p>
 *
 *@Author cong.zhang
 *@Version 1.0.0
 *@Date 2020/7/26
 *@Time 23:54
 */
@Service
public class SystemServiceImpl implements ISystemService {

    @Autowired
    private ISysUserDao sysUserDao;
    @Autowired
    private ISysUserRoleDao sysUserRoleDao;
    @Autowired
    private ISysMenuDao sysMenuDao;
    @Autowired
    private ISysMenuRoleDao sysMenuRoleDao;
    @Autowired
    private ISysRoleDao sysRoleDao;

    /**
     * 后台管理系统-用户管理-查询
     *
     * @param ro
     * @param pageRequest
     * @return
     */
    @Override
    public DataTableRO getSysUserList(SysUserRO ro, PageRequest pageRequest) {
        List list = sysUserDao.list(ro, pageRequest);
        DataTableRO dataTableRO = new DataTableRO();
        int allCount = sysUserDao.total(ro);
        int pageSize = pageRequest.getSize();
        dataTableRO.setAll_count(allCount);
        dataTableRO.setList(list);
        dataTableRO.setCurrent_page(pageRequest.getPage());
        dataTableRO.setPage_size(pageSize);
        int allPage = (allCount % pageSize == 0 ? allCount / pageSize : allCount / pageSize + 1);
        dataTableRO.setAll_page(allPage);
        return dataTableRO;
    }

    /**
     * 后台管理系统-用户管理-新增
     *
     * @param sysUser
     * @return
     */
    @Override
    public ActionResultRO saveSysUser(SysUserRO sysUser) {
        boolean b = sysUserDao.ifExistsPhone(sysUser.getPhone());
        if(b){
          return new ActionResultRO(false, "用户已经存在，不能新增");
        }

        // 获取随机密码
        String password = CommonUtil.generatePassword(12);
        // 设置密码sha256编码
        String passwordSha256= SHA256Enhanced.sha256(password);
        sysUser.setPassword(passwordSha256);

        int rn = sysUserDao.install(sysUser);
        return new ActionResultRO(rn, "保存成功,您的初始密码为：" + password, "保存失败");
    }

    /**
     * 后台管理系统-用户管理-修改
     *
     * @param sysUser
     * @return
     */
    @Override
    public ActionResultRO editSysUser(SysUserRO sysUser) {
        int rn = sysUserDao.update(sysUser);
        return new ActionResultRO(rn, "用户修改成功", "用户修改失败");
    }

    /**
     * 后台管理系统-用户管理-批量删除
     *
     * @param ids
     * @return
     */
    @Override
    public ActionResultRO delSysUser(Long[] ids) {

        //删除关联表-用户角色表
        sysUserRoleDao.remove(ids[0]);    // 这里删除失败

        //删除用户表
        int rn = sysUserDao.remove(ids);

        return new ActionResultRO(rn, "用户删除成功", "用户删除失败");
    }

    /**
     * 后台管理系统-菜单查询
     *
     * @return
     */
    @Override
    public List getSysMenuList() {
        return sysMenuDao.findAll();
    }

    /**
     * 获取指定菜单
     *
     * @param sysMenu
     * @return
     */
    @Override
    public SysMenuRO getSysMenu(SysMenuRO sysMenu) {
        return sysMenuDao.findOneById(sysMenu.getId());
    }

    /**
     * 后台管理系统-新增菜单
     *
     * @param sysMenu
     * @return
     */
    @Override
    public ActionResultRO saveSysMenu(SysMenuRO sysMenu) {
        int rn = sysMenuDao.install(sysMenu);

        if (sysMenu.getParent_id() > 0) {
            sysMenuDao.update(sysMenu);
        }

        if (rn > 0) {
            // 新增菜单时调用，实现管理员可操作所有菜单功能
            SysMenuRoleRO menuRole = new SysMenuRoleRO();
            menuRole.setMenu_id(Long.valueOf(rn));
            menuRole.setRole_id(Long.valueOf(-1));
            menuRole.setCreate_user_id(sysMenu.getCreate_user_id());
            menuRole.setCreate_time(sysMenu.getCreate_time());
            menuRole.setStatus(sysMenu.getStatus());
            rn = sysMenuRoleDao.install(menuRole);
        }

        return new ActionResultRO(rn, "菜单保存成功", "菜单保存失败");
    }

    /**
     * 后台管理系统-编辑菜单
     *
     * @param ro
     * @return
     */
    @Override
    public ActionResultRO editSysMenu(SysMenuRO ro) {
        int rn = sysMenuDao.update(ro);
        return new ActionResultRO(rn, "修改成功", "修改失败");
    }

    /**
     * 后台管理系统-删除菜单
     *
     * @param menuId 菜单ID
     * @return
     */
    @Override
    public ActionResultRO delSysMenu(Long menuId) {
        String msg = "";
        String errMsg = "";
        int rn = 0;
        //检查菜单是否被引用，否则不能删除
        if (sysMenuRoleDao.ifExists(menuId, Long.valueOf(0L))) {
            msg = "菜单被角色引用，不能删除";
            errMsg = "菜单被角色引用，不能删除";
        } else {

            // 删除菜单角色关系数据
            sysMenuRoleDao.remove(menuId, -1L);

            //删除子菜单
            List<SysMenuRO> secondAll = sysMenuDao.findAllByParentId(menuId);
            if (CollectionUtils.isNotEmpty(secondAll)) {
                for (SysMenuRO second : secondAll) {
                    long secondParentId = second.getId();
                    //三级菜单
                    List<SysMenuRO> thirdAll = sysMenuDao.findAllByParentId(secondParentId);
                    if (CollectionUtils.isNotEmpty(thirdAll)) {
                        for (SysMenuRO third : thirdAll) {
                            long thirdParentId = third.getId();
                            sysMenuRoleDao.remove(thirdParentId, Long.valueOf(-1));
                        }
                    }
                    sysMenuDao.remove(secondParentId, null);
                    sysMenuRoleDao.remove(secondParentId, Long.valueOf(-1));
                }
                sysMenuDao.remove(menuId,null);
            }
            //删除本菜单
            rn = sysMenuDao.remove(null, menuId);
            msg = "删除成功";
            errMsg = "删除失败";
        }
        return new ActionResultRO(rn, msg, errMsg);
    }

    /**
     * 后台管理系统-角色查询
     *
     * @param sysRole
     * @return
     */
    @Override
    public DataTableRO getSysRoleList(SysRoleRO sysRole, PageRequest pageRequest) {
        List<SysRoleRO> list = sysRoleDao.list(sysRole, pageRequest);

        DataTableRO dataTableRO = new DataTableRO();
        int allCount = sysRoleDao.total(sysRole);
        int pageSize = pageRequest.getSize();
        dataTableRO.setAll_count(allCount);
        dataTableRO.setList(list);
        dataTableRO.setCurrent_page(pageRequest.getPage());
        dataTableRO.setPage_size(pageSize);
        int allPage = (allCount % pageSize == 0 ? allCount / pageSize : allCount / pageSize + 1);
        dataTableRO.setAll_page(allPage);
        return dataTableRO;
    }

    /**
     * 后台管理系统-新增角色
     *
     * @param roleDto
     * @return
     */
    @Override
    public ActionResultRO saveSysRole(SysRoleDTO roleDto) {
        int rn = sysRoleDao.install(roleDto);
        SysMenuRoleRO sysMenuRoleRO = null;

        //增加菜单角色表记录
        if (null != roleDto.getMenuIds() && roleDto.getMenuIds().length > 0) {
            List<SysMenuRoleRO> list = new ArrayList();
            for (Long menuId : roleDto.getMenuIds()) {
                sysMenuRoleRO = new SysMenuRoleRO();
                sysMenuRoleRO.setMenu_id(menuId);
                sysMenuRoleRO.setRole_id(Long.valueOf(rn));
                sysMenuRoleRO.setCreate_user_id(Long.valueOf(-1));
                sysMenuRoleRO.setCreate_time(System.currentTimeMillis());
                sysMenuRoleRO.setStatus(StatusTypes.OnLine.getStatus());
                list.add(sysMenuRoleRO);
            }

            sysMenuRoleDao.installBatch(list);
        }

        if (rn > 0) {
            rn = 1;
        }

        return new ActionResultRO(rn, "保存成功", "保存失败");
    }

    /**
     * 后台管理系统-修改角色
     *
     * @param roleDto
     * @return
     */
    @Override
    public ActionResultRO editSysRole(SysRoleDTO roleDto) {
        long roleId = roleDto.getId();

        // 修改菜单角色表（包括增加、编辑、删除）
        int row = sysMenuRoleDao.remove(null, roleId);
        System.out.println("delete sys_menu_role row :" + row);
        SysMenuRoleRO sysMenuRoleRO = null;

        //重新增加
        if (null != roleDto.getMenuIds() && roleDto.getMenuIds().length > 0) {
            List<SysMenuRoleRO> list = new ArrayList();
            for (Long menuId : roleDto.getMenuIds()) {
                sysMenuRoleRO = new SysMenuRoleRO();
                sysMenuRoleRO.setMenu_id(menuId);
                sysMenuRoleRO.setRole_id(roleId);
                sysMenuRoleRO.setCreate_user_id(Long.valueOf(-1));
                sysMenuRoleRO.setCreate_time(System.currentTimeMillis());
                sysMenuRoleRO.setStatus(StatusTypes.OnLine.getStatus());
                list.add(sysMenuRoleRO);
            }

            sysMenuRoleDao.installBatch(list);
        }

        int rn = sysRoleDao.update(roleDto);
        return new ActionResultRO(rn, "修改成功", "修改失败");
    }

    /**
     * 后台管理系统-删除角色
     *
     * @param ids
     * @return
     */
    @Override
    public ActionResultRO delSysRole(Long ids[]) {
        int rn = 0;
        String msg = "";
        String errMsg = "";

        for (int i = 0; i < ids.length; i++) {
            long roleId = ids[i];
            SysRoleRO sysRole = sysRoleDao.findOneById(roleId);

            // 1、删除用户角色表中的记录,（角色不存在，不能删除）
            if (sysRole == null) {
                errMsg += "角色 Id = [ " + roleId + " ] 不存在，不能删除;";
                continue;
            }

            // 1、删除用户角色表中的记录,（角色被引用，不能删除）
            if (sysUserRoleDao.ifExists(roleId)) {
                msg += "角色 [ " + sysRole.getRole_name() + " ] 被引用，不能删除;";
                errMsg += "角色 [ " + sysRole.getRole_name() + " ] 被引用，不能删除;";
                continue;
            }

            // 2、删除菜单角色表中的记录
            sysMenuRoleDao.remove(null,roleId);

            //3、删除角色表中记录
            rn = sysRoleDao.remove(roleId);
            msg += "角色 [ " + sysRole.getRole_name() + "] 删除成功;";
        }

        return new ActionResultRO(rn, msg, errMsg.equals("") ? "删除失败" : errMsg);
    }

    /**
     * 根据角色id获取菜单角色记录
     *
     * @param sysRole
     * @return
     */
    @Override
    public List<SysMenuRoleRO> getMenuRoleById(SysRoleRO sysRole) {
        Set<Long> roleIds = new HashSet<Long>();
        if (sysRole != null && sysRole.getId() != null) {
            roleIds.add(sysRole.getId());
        }
        return sysMenuRoleDao.findAllByIds(roleIds);
    }

    /**
     * 后台管理系统-根据用户id获取角色集合
     *
     * @param sysUser
     * @return
     */
    @Override
    public ActionResultRO getRolesByUserId(SysUserRO sysUser) {
        return new ActionResultRO(true, "ok", sysUserRoleDao.findAllRoleByIds(sysUser.getId()));
    }


    /**
     * 后台管理系统-分配角色
     *
     * @param userDto
     * @param pageRequest
     * @return
     */
    @Override
    public ActionResultRO editUserRole(SysUserDTO userDto, PageRequest pageRequest) {
        int rn = 0;

        // 先用户角色关联全部数据
        rn = sysUserRoleDao.remove(userDto.getId());

        SysUserRoleRO sysUserRoleRO = null;
        // 后增加
        if (null != userDto.getRoleIds() && userDto.getRoleIds().length > 0) {
            List list = new ArrayList();
            for (Long roleId : userDto.getRoleIds()) {
                sysUserRoleRO = new SysUserRoleRO();

                sysUserRoleRO.setUser_id(userDto.getId());
                sysUserRoleRO.setRole_id(roleId);
                sysUserRoleRO.setCreate_user_id(userDto.getCreate_user_id());
                sysUserRoleRO.setCreate_time(System.currentTimeMillis());
                sysUserRoleRO.setStatus(userDto.getStatus());
                list.add(sysUserRoleRO);
            }

            // 批量增加 用户角色中间表
            sysUserRoleDao.insertBatch(list);
        }

        return new ActionResultRO(true, "保存成功");
    }

    /**
     * 获取页面头部菜单导航
     *
     * @param menuId
     * @return
     */
    @Override
    public ReturnMap showMenuHead(Long menuId) {
        SysMenuRO sysMenu = sysMenuDao.findOneById(menuId);
        String menuHead = "";
        if (null != sysMenu) {
            menuHead = sysMenu.getMenu_name();
            if (sysMenu.getParent_id() != 0) {
                SysMenuRO parentMenu = sysMenuDao.findOneById(sysMenu.getParent_id());
                if (null != parentMenu) {
                    menuHead = parentMenu.getMenu_name() + " &nbsp; > &nbsp; " + menuHead;
                }
                SysMenuRO grandParents = sysMenuDao.findOneById(parentMenu.getParent_id());
                if (null != grandParents) {
                    menuHead = grandParents.getMenu_name() + " &nbsp; > &nbsp; " + menuHead;
                }
            }
        }
        ReturnMap obj = new ReturnMap();
        obj.put("location", menuHead);
        obj.put("help", sysMenu.getMenu_desc());
        return obj;
    }

    @Override
    public SysUserRO getSysUser(Long userId) {
        return sysUserDao.findOneById(userId);
    }

    /**
     * 系统用详细信息
     * @param sysUser
     * @return
     */
    @Override
    public SysUserRO getSysUser(SysUserRO sysUser) {
        SysUserRO sysUserRO = sysUserDao.findOneById(sysUser.getId());
        return sysUserRO;
    }

    /**
     * 根据用户ID 查找角色信息
     *
     * @param userId
     * @return
     */
    @Override
    public SysRoleRO getRoleInfoByUserId(Long userId) {
        return sysRoleDao.findOneByUserId(userId);
    }

    /**
     * 根据角色名获取
     *
     * @param roleName
     * @return
     */
    @Override
    public List<SysUserSnapDTO> getUserInfoByRoleName(String roleName){
        return sysUserDao.findAllByRoleName(roleName);
    }

    /**
     *
     * @param cnNames
     * @return
     */
    @Override
    public List<SysUserRO> getUserInfoByCnName(List<String> cnNames) {
        return sysUserDao.findAllByCnName(cnNames);
    }

    /**
     *
     * @param id
     * @param status
     * @param desc
     * @return
     */
    @Override
    public ActionResultRO updateSysUserStatus(long id, int status, String desc) {
        int rn = sysUserDao.updateStatus(id, status);
        return new ActionResultRO(rn, desc + "成功", desc + "失败");
    }


}
